<template>
  <div class="full-box d-flex overflow-hidden">
    <BKTabs
      class="flex-0"
      v-model="current"
      :data="tabs"
      tab-position="left"
    />
    <div class="flex-1 overflow-hidden bg-white">
      <ConfigGrid
        v-show="['0', '1', '2', '5', '6'].includes(current)"
        ref="grid"
        :has-add="false"
        :has-batch-remove="false"
        :configs="currentConfigs"
      />
      <div
        v-show="current==='3'"
        class="full-height d-flex-c"
      >
        <div class="flex-0 flex-between p-a-mini b-b">
          <div class="d-flex ai-c">
            <label class="m-r-mini f-14">日志行数</label>
            <el-input-number
              size="mini"
              v-model="line"
              :step="100"
            />
          </div>
          <div>
            <el-tooltip content="刷新日志">
              <el-button
                size="mini"
                icon="el-icon-refresh"
                circle
                @click="getConsoleLog"
              />
            </el-tooltip>
            <el-tooltip content="导出日志">
              <el-button
                :disabled="exporting"
                size="mini"
                icon="el-icon-download"
                circle
                @click="exportLog"
              />
            </el-tooltip>
          </div>
        </div>
        <div
          ref="container"
          class="flex-1 overflow-auto m-a-mini b-a br-8 bg-grey"
        >
          <p
            :class="`${l.type}-text`"
            v-for="(l, i) in consoleLogs"
            :key="i"
          >
            {{ l.text }}
          </p>
        </div>
      </div>
    </div>
    <BKModal
      v-model="detailVisible"
      title="日志详情"
      width="80%"
      height="80%"
    >
      <div class="full-height overflow-auto">
        <div class="p-h-s">
          <div class="f-14 c-grey m-v-mini">
            操作参数
          </div>
          <BKCodeEditor
            style="height: 300px;"
            ref="editor1"
          />
          <div class="f-14 c-grey m-v-mini">
            操作结果
          </div>
          <BKCodeEditor
            style="height: 300px;"
            ref="editor2"
          />
          <div class="f-14 c-grey m-v-mini">
            JSON结果
          </div>
          <BKCodeEditor
            language="json"
            style="height: 300px;"
            ref="editor3"
          />
          <div class="f-14 c-grey m-v-mini">
            错误信息
          </div>
          <BKCodeEditor
            style="height: 300px;"
            ref="editor4"
          />
        </div>
      </div>
    </BKModal>
    <BKModal
      v-model="searchModalVisible"
      :mask="false"
      :lock-view="false"
      :lock-scroll="false"
      :loading="searching"
      title="日志搜索"
      width="80%"
      height="80%"
    >
      <div class="full-box p-a-mini">
        <div
          ref="searchResult"
          class="full-box overflow-auto b-a br-8 bg-grey"
        >
          <p
            :class="`info-text`"
            v-for="(l, i) in searchResult"
            :key="i"
          >
            {{ l }}
          </p>
          <div
            class="flex-ai-c jc-c full-box"
            v-if="!searchResult.length"
          >
            <el-empty content="暂无数据" />
          </div>
        </div>
      </div>
    </BKModal>
    <ConfigForm
      :configs="formConfigs"
      ref="form"
    />
  </div>
</template>

<script>
import request from '@/utils/request'

const appId = 'watf'
const bzCode = 'WATF'

export default {
  name: 'DataSource',
  data () {
    return {
      current: '0',
      tabs: [
        { name: '0', label: '登录日志' },
        { name: '1', label: '操作日志' }
      ],
      configs: {
        0: {
          dataUrl: '/log/getLoginLog',
          noOperation: true,
          noParentParam: true,
          module: '登录日志',
          appId,
          bzCode,
          metaSet: 'WATF_B_SYS_LOGIN_LOG'
        },
        1: {
          dataUrl: '/log/getOperLog',
          noOperation: true,
          noParentParam: true,
          module: '操作日志',
          appId,
          bzCode,
          metaSet: 'WATF_B_SYS_OPER_LOG',
          afterFetchColumns: this.afterFetchColumns
        }
      },
      currentConfigs: {},
      line: 1000,
      consoleLogs: [],
      exporting: false,
      detailVisible: false,
      detailModel: {},
      searchLogInited: false,
      searching: false,
      searchModalVisible: false,
      searchResult: [],
      formConfigs: {},
      plumeLogInited: false
    }
  },
  watch: {
    current: {
      immediate: true,
      handler (v) {
        if (v === '3') {
          if (!this.consoleLogInited) {
            this.consoleLogInited = true
            this.getConsoleLog()
          }
        } else if (v === '4') {
          this.searchLogInited = true
        } else if (v === '7') {
          this.plumeLogInited = true
        } else {
          this.currentConfigs = this.configs[v]
          this.$nextTick(() => {
            this.$refs.grid.reload()
          })
        }
      }
    }
  },
  methods: {
    async getConsoleLog () {
      const data = await request.post('/log/console', { line: this.line })
      let lastType = 'info'
      this.consoleLogs = data.map(r => {
        let model = {}
        if (r.indexOf('ERROR') !== -1) {
          model = { text: r, type: 'error' }
        } else if (r.indexOf('WARN') !== -1) {
          model = { text: r, type: 'warning' }
        } else if (r.indexOf('INFO') !== -1) {
          model = { text: r, type: 'info' }
        } else {
          model = { text: r, type: lastType }
        }
        lastType = model.type
        return model
      })
      this.$nextTick(() => {
        this.$refs.container.scrollTo(0, this.$refs.container.scrollHeight)
      })
    },
    async exportLog () {
      this.exporting = true
      const { data, fileName } = await request.getFileStreamByPost('/log/export')
      request.downloadBlobFile(data, fileName)
      this.exporting = false
      this.$message.success('下载成功！')
    },
    afterFetchColumns (columns) {
      return columns.concat([
        {
          field: 'operation',
          title: '操作',
          fixed: 'right',
          width: 80,
          slots: {
            default: ({ row }) => {
              return [
                <div class="operation-icon-buttons">
                  <i class="el-icon-search" title="搜索日志" onClick={() => { this.searchDetail(row) }}></i>
                  <i class="el-icon-document" title="详情" onClick={() => { this.showDetail(row) }}></i>
                </div>
              ]
            }
          }
        }
      ])
    },
    pushAfterFetchColumns (columns) {
      return this.addDetailOperation(columns, 5)
    },
    pullAfterFetchColumns (columns) {
      return this.addDetailOperation(columns, 6)
    },
    addDetailOperation (columns, type) {
      return columns.concat([
        {
          field: 'operation',
          title: '操作',
          fixed: 'right',
          width: 50,
          slots: {
            default: ({ row }) => {
              return [
                <div class="operation-icon-buttons">
                  <i class="el-icon-document" title="详情" onClick={() => { this.showServiceDetail(row, type) }}></i>
                </div>
              ]
            }
          }
        }
      ])
    },
    showServiceDetail (row, type) {
      this.formConfigs = this.configs[type]
      this.$nextTick(() => {
        this.$refs.form.viewDetail(row)
      })
    },
    async showDetail (row) {
      this.detailVisible = true
      const data = await request.post('/SingleTable/curd', {
        appId,
        bzCode,
        metaSet: 'WATF_B_SYS_OPER_LOG_RESULT',
        methodCode: 'select',
        methodParams: JSON.stringify({
          queryParam: {
            OPER_ID: row.OPER_ID
          }
        })
      })
      this.detailModel = data.rows[0]
      this.$nextTick(() => {
        this.$refs.editor1.init(this.detailModel.OPER_PARAM || '')
        this.$refs.editor2.init(this.detailModel.OPER_RESULT || '')
        this.$refs.editor3.init(this.detailModel.JSON_RESULT || '')
        this.$refs.editor4.init(this.detailModel.ERROR_MSG || '')
      })
    },
    async searchDetail (row) {
      this.searchModalVisible = true
      this.searching = true
      const data = await request.post('/log/logById', row)
      this.searching = false
      this.searchResult = data
      this.$nextTick(() => {
        this.$refs.searchResult.scrollTo(0, this.$refs.searchResult.scrollHeight)
      })
    }
  }
}
</script>

<style lang="scss" scoped>
::v-deep {
  .error-text,
  .warning-text,
  .info-text {
    margin: 0;
    line-height: 1.5;
    font-size: 14px;
    padding: 5px;
  }

  .error-text {
    background: #f56c6c;
    color: #fff;
  }

  .warning-text {
    background: #e6a23c;
    color: #fff;
  }
}
</style>
